home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
music4c.sit
/
Music4C Folder
/
Sources Folder
/
ugens.h
< prev
Wrap
Text File
|
1990-09-09
|
11KB
|
462 lines
/*
* ⌐ Graeme Gerrard 1990
* Faculty of Music, University of Melbourne
* Parkville Victoria 3052 Australia.
*
* ARPANET: grae@murdu.ucs.unimelb.edu.au
* telephone: (613) 344 4127, Fax: (613) 344 5346
*/
int yyI1, yyI2, yyI3, yyI4;
double yyA1, yyA2, yyA3, yyA4, yyA5, yyA6;
/*-----------------------------------------------------------------*/
#define Mono(output)\
out[loc] += (output)
#define Stereo(output, prop)\
out[loc] += (output) * (prop);\
out[loc+1] += (output) * (1.0 - (prop))
#define Output(a, b, c, d)\
switch(nchnls) {\
case 4: out[loc+3] += d;\
case 3: out[loc+2] += c;\
case 2: out[loc+1] += b;\
case 1: out[loc] += a;\
}
#define Oscil(sig, amp, si, fno, phs)\
/* truncating digital oscillator, negative samp incs ok */\
sig = (amp) * (*(F[(fno)] + ((int)((phs)+1.0))));\
(phs) += (si);\
while ((phs) < 0.0) (phs) += *(F[(fno)]);\
while ((phs) >= (*(F[(fno)]))) (phs) -= *(F[(fno)])
#define Oscil1(sig, amp, si, fno, phs)\
/* truncating function lookup, samples function once,
* holds last value if phs exceeds *(F[(fno)]) (i.e. function length) */\
if ((phs) >= *(F[(fno)]))\
sig = (amp) * *(F[(fno)] + (int)*(F[(fno)]));\
else {\
if ((phs) <= 0.0 ) sig = (amp) * *(F[(fno)] + 1);\
else sig = (amp) * *(F[(fno)] + (int)((phs)+1.0));\
(phs) += (si);\
}
#define Osci1(sig, amp, si, fno, phs)\
/* interpolating version of Oscil1 */\
if ((phs) >= *(F[(fno)])\
sig = (amp) * (*(F[(fno)] + (int)*(F[(fno)]));\
else {\
if ((phs) <= 0.0 ) sig = (amp) * (*(F[(fno)] + 1));\
else {\
yyI1 = (phs) + 1.0;\
yyI2 = yyI1 + 1;\
yyA1 = (phs) - (int)(phs);\
sig = (amp) * ( (*(F[(fno)]+yyI1)) + \
( (*(F[(fno)]+yyI2)) - (*(F[(fno)]+yyI1))) * yyA1)\
}\
(phs) += (si);\
}
#define Oscili(sig, amp, si, fno, phs)\
/* interpolating digital oscillator, negative samp incs ok */\
yyI1 = (int)(phs) + 1;\
yyI2 = (yyI1 % (int)*(F[(fno)])) + 1;\
yyA1 = (phs) - (int)(phs);\
(phs) += (si);\
while ((phs) < 0.0) (phs) += *(F[(fno)]);\
while ((phs) >= (*(F[(fno)]))) (phs) -= *(F[(fno)]);\
sig = (amp) * ( (*(F[(fno)]+yyI1)) + \
( (*(F[(fno)]+yyI2)) - (*(F[(fno)]+yyI1))) * yyA1)
#define Nonlin(sig, amp, x, fno)\
/* interpolating lookup of transfer function for non-linear distortion
* (waveshaping) */\
yyI1 = (x) + (int)(*(F[(fno)])/2.0) + 1;\
if ( yyI > *(F[(fno)]-1.0)) yyI1 = (int)*(F[(fno)]);\
else if ( yyI1 < 1 ) yyI1 = 1;\
yyI2 = yyI1 + 1;\
yyA1 = (x) - (int)(x);\
sig = (amp) * ( (*(F[(fno)]+yyI1)) + \
( (*(F[(fno)]+yyI2)) - (*(F[(fno)]+yyI1))) * yyA1)
/*-----------------------------------------------------------------
* Various conversion routines, usually assuming 512 length functions
*/
#define Cycle(cps)\
/* cps to samp inc */\
((cps) * 512.0 / srate)
#define Sicps(si)\
/* samp inc to cps */\
(((si) * srate) / 512.0)
#define Period(dur)\
/* duration to samp inc */\
(512.0 / srate / (dur))
#define Pitch(pch)\
/* 8ve.pc to samp inc */\
yyA1 = (int)(pch)\
pow(2.0, ( yyA1 + 8.333333 * (pch - oct) )) * 523.2511 / srate
#define Cpsoct(oct)\
/* linear octave form to cps, Mid C = octave 8 */\
pow(2.0, (oct) ) * 1.021975
#define Cpspch(pch)\
/* 8ve.pc to cps */\
yyA1 = (int)(pch)\
pow(2.0, ( yyA1 + 8.333333 * (pch - oct) )) * 1.021975
#define Octave(oct)\
/* linear octave form to samp inc */\
pow(2.0, (oct) ) * 523.2511 / srate
#define Octcps(cps)\
/* cps to linear octave form */\
log( (cps) / 1.021975 ) / 0.69314718
#define Octpch(pch)\
/* 8ve.pc to linear octave */\
(int)(pch) + 8.333333 * ((pch) - (int)(pch))
#define Pchcps(cps)\
/* cps to 8ve.pc */\
Pchoct( Octcps((cps)) )
#define Pchoct(oct)\
/* linear octave form to 8ve.pc */\
0.12 * ( (oct) - (int)(oct) ) + (int)(oct)
/*-----------------------------------------------------------------*/
/*
have to call this dRandom, Mac Toolbox has a function called Random
*/
#define dRandom(x)\
(double) ((1061 * (int)((x)*1048576.0) + 221589) % 1048576) / 1048576.0
#define Rand(sig, amp, a)\
a = dRandom(a);\
sig = (amp) * ( 1.0 - (2.0 * a));
#define Randh(sig, amp, si, a)\
*(a) += (si);\
if ( *(a) >= 512.0) {\
*(a+1) = dRandom(*(a+1));\
*(a) -= 512.0;\
}\
sig = *(a+1) * (amp)
#define Randi(sig, amp, si, a)\
*(a) += (si);\
if ( *(a) > 1.0 ) {\
*(a) -= 1.0;\
*(a+1) = *(a+2);\
*(a+2) = dRandom( *(a+2) );\
*(a+3) = 2.0 * ( *(a+1) - *(a+2) );\
*(a+1) = 1.0 - ( *(a+1) * 2.0 ) - (*(a+3) * *(a) );\
}\
sig = ( *(a+1) + *(a+3) * *(a) ) * (amp)
#define Randfi(sig, amp, freq, a )\
yyA1 = *(a+3) / (srate / (freq));\
if ( yyA1 >= 1.0) {\
*(a+3) = 0.0;\
yyA1 = 0.0;\
}\
if ( *(a+3) == 0.0 ) {\
*(a+1) += *(a+2);\
Randf( *(a+2), *(a+1), *(a+4), *(a) ) - *(a+1);\
}\
*(a+3) += 1.0;\
sig = (amp) * ( *(a+1) + ( yyA1 * *(a+2)) )
#define Randf(sig, oldval, factor, seed)\
yyA1 = 2.0 - ( 2.0 * (factor));\
yyA2 = (oldval) - yyA1;\
if ( yyA2 < -1.0) yyA2 = -1.0;\
yyA3 = (oldval) + yyA1;\
if ( yyA3 > 1.0) yyA3 = 1.0;\
seed = dRandom((seed));\
sig = yyA1 + ((yyA2-yyA1) * (seed))
/*-----------------------------------------------------------------*/
#define Envel3(sig, amp, fno, a )\
if ( *(a+3) < 128.0) {\
*(a+3) += *(a);\
if (*(a+3) > 128.0) *(a+3) = 128.0;\
}\
else if (*(a+4) < 256.0) {\
*(a+3) += *(a+1);\
if (*(a+3) > 256.0) *(a+3) = 256.0;\
}\
else if (*(a+4) < 384.0) {\
*(a+3) += *(a+2);\
if (*(a+3) > 384.0) *(a+3) = 384.0;\
}\
else\
*(a+3) = 384.0;\
yyI1 = (int)(*(a+3) + 1.5);\
sig = (amp) * (*(F[(fno)] + yyI1))
/*-----------------------------------------------------------------*/
#define Alpass(sig, xin, rvt, a)\
Comb(yyA1, (xin), (rvt), a);\
yyI1 = *(a+4);\
sig = yyA1 - *(a+3) - *(a+yyI1)
#define Balnce(sig, y, x, a)\
Tone(yyA1, (y) * (y), (a+3));\
if ( yyA1 == 0.0 ) yyA1 = 0.00000001;\
Tone(yyA2, (x) * (x), a);\
sig = (y) * sqrt( yyA2 ) / yyA1
#define Comb(sig, xin, rvt, a)\
if ( rvt != *(a+2)) {\
if ( rvt == 0.0 ) *(a+3) = 0.0;\
else *(a+3) = pow(0.001, *(a+1) / rvt );\
*(a+3) = 0.0;\
*(a+2) = rvt;\
}\
if ( *(a+4) >= *(a)) *(a+4) = 5.0;\
else *(a+5) += 1;\
yyI1 = (int)*(a+4);\
sig = *(a+yyI1);\
*(a+yyI1) = (*(a+yyI1) * *(a+3)) + (xin)
/*-----------------------------------------------------------------*/
#define Buzz(sig, amp, si, hn, fno, phs )\
yyI1 = (phs);\
yyI2 = (yyI1+1) % 1024;\
yyA1 = 2.0 * hn;\
yyA2 = yyA1 + 1.0;\
yyA3 = (int)( (phs - (int)phs) * yyA2) / yyA2;\
yyA4 = (*(F[(fno)] + yyI1 + 1));\
yyA5 = (*(F[(fno)] + yyI2 + 1));\
yyA4 += (yyA5 - yyA4) * yyA3;\
if ( yyA4 == 0.0 ) sig = (amp);\
else {\
yyI2 = (int)(yyA2 * (phs)) % 1024;\
sig = (amp) * ((*(F[(fno)] + yyI2 + 1)) / yyA4 - 1.0) / yyA1;\
}\
(phs) += (si);\
while ((phs) >= 1024.0) (phs) -= 1024.0
/*-----------------------------------------------------------------*/
#define Envlp(sig, amp, nf1, nf2, a )\
yyA1 = Oscil1(sig, (amp), *(a), nf1, *(a+1));\
sig = Oscil1(yyA1, *(a+2), nf2, *(a+3));\
sig += *(a+4)
/*-----------------------------------------------------------------*/
#define Add8vepc(res, p1, p2)\
/* adds together 2 8ve.pc pitches */\
yyI2 = (int)(p1);\
yyA1 = (p1) - yyI2;\
yyI3 = (int)p2;\
if ( yyI3 < 0 ) {\
yyI1 = -yyI3;\
yyA2 = (p2) + (double)yyI1;\
}\
else\
yyA2 = (p2) - (double)yyI3;\
yyA3 = (yyA1+yyA2) * 100.0; /* shift for roundoff/truncation */\
yyI4 = (int)(yyA3/12.0) + yyI2 + yyI3;\
if ( yyA3 < 0.0 ) {\
yyI4 -= 1;\
yyA4 = (12.0 + (int)yyA3 % 12) / 100.0;\
}\
else {\
yyA4 = ((int)yyA3 % 12) / 100.0;\
}\
res = yyI4+yyA4
#define Expon(sig, a, b)\
(*a) *= (*b);\
sig = (*a)
/* not checked out yet */
#define Formnt( sig, rms, si, fno1, fno2, fno3, fno4, a)\
/* a[0] = overall phase */\
/* a[1] = previous sum of squares */\
/* a[2] = rescaling divisor */\
yyA2 = 0.0;\
if ( (rms) == 0.0 ) {\
yyA3 = 0.0;\
for ( yyI1 = 1; yyI1 < 508; yyI1 += 3 ) {\
yyA6 = *(F[(fno2)]+yyI1);\
if ( yyA6 == 0.0 )\
break;\
yyI2 = (int)(yyA6 * (si) * 2.0 + 1.5);\
if ( yyI2 > 512)\
break;\
yyA5 = *(F[(fno2)]+yyI1+1) * *(F[(fno3)]+yyI2);\
if ( (fno4) <= 0)\
yyA1 = yyA5;\
else\
yyA1 = yyA5 / *(F[(fno4)]+yyI2);\
yyA2 += (yyA1 * yyA1 );\
yyI3 = ((int)((yyA6 * *a) + *(F[(fno2)]+yyI1+2)) % 512) + 1.0;\
yyA3 += yyA5 * *(F[(fno1)]+yyI3);\
}\
}\
yyA4 = (*a+(si));\
yyA1 = yyA4 / 65536.0;\
*a = yyA4 - ((int)yyA1 * 65536.0);\
if ( yyA2 != 0.0 ) {\
if ( yyA2 != *(a+1)) {\
*(a+2) = sqrt(yyA2 / 2.0);\
*(a+1) = yyA2;\
}\
else\
sig = yyA3 * (rms) / *(a+2);\
}\
sig = 0.0
#define Linens(sig, amp, a)\
*(a+3) += 1.0;\
if ( *(a+3) <= *(a)) {\
*(a+6) += *(a+4);\
sig = (amp) * *(a+6);\
}\
else if ( *(a+3) <= *(a+2)) sig = (amp);\
else if ( *(a+3) > *(a+2)) {\
*(a+7) -= *(a+5);\
sig = (amp) * *(a+7);\
}\
else sig = 0.0
#define Hpf2(sig, y, a )\
/* 2nd order high pass filter,\
* digital recursion formula parameter assignments:\
* *a = y1, *(a+1) = y2, *(a+2) = z1, *(a+3) = z2, *(a+4) = p0,\
* *(a+5) = q1, *(a+6) = q2.\
*/\
sig = *(a+4) * ( (y)-*a-*a+*(a+1)) + *(a+5) * *(a+2) + *(a+6) * *(a+3);\
*(a+1) = *a;\
*a = (y);\
*(a+3) = *(a+2);\
*(a+2) = sig
#define Randfc(sig, amp, freq, a, curv, cdiff)\
yyA2 = ((128.0 / srate) * *(a+3) * (freq) );\
if ( yyA2 > 128.0) {\
*(a+3) = 0.0;\
yyA2 = 0;\
}\
if ( *(a+3) == 0.0 ) {\
*(a+1) += *(a+2);\
Randf(*(a+2), *(a+1), *(a+4), *(a))\
*(a+2) -= *(a+1);\
}\
*(a+3) += 1.0;\
yyI1 = (int)yyA2;\
yyA1 = *(curv+yyI1) + (*(cdiff+yyI1) * ( yyA2 - yyI1));\
sig = (amp) * ( *(a+1) + ( yyA1 * *(a+2))))\
#define Reson( x, a )\
/* y[i] = a[0] * x[i] + a[1] * y[i-1] - a[2] * y[i-2] */\
yyA1 = *a * (x) + *(a+1) * *(a+3) - *(a+2) * *(a+4);\
*(a+4) = *(a+3);\
*(a+3) = yyA1;\
sig = yyA1\
#define Slope(sig, a, b)\
(*a) += (*b);\
sig = (*a)
#define Tone(sig, x, a )\
*(a+2) = (*(a) * (x)) + (*(a+1) * *(a+2));\
sig = *(a+2)
#define Vreson(sig, xin, cf, bw, fl, fno, a)\
yyA2 = 1.0 - 3.1415926 * (bw) / srate;\
*(a+2) = yyA2 * yyA2;\
yyA2 = 4.0 * *(a+2) / (1.0 + *(a+2));\
yyA1 = (fl) * (cf) / srate;\
Vfmult(*(a+1), yyA2, yyA1, (fno));\
Reson(sig, (xin), a))
#define Vfmult(sig, amp, sl, fno)\
yyI1 = ((int)(sl) % (int)*(F[(fno)])) + 1;\
sig = (amp) * *(F[(fno)] + yyI1)
#define Ilook(sig, x, fno)\
/* interpolating table lookup */\
yyI1 = (int)(x);\
if ( yyI1 < 1 ) sig = (*(F[(fno)] + 1));\
else if (yyI1 >= (int)*(F[(fno)])) sig = (*(F[(fno)] + *(F[(fno)])));\
else {\
yyI2 = yyI1 + 1;\
yyA1 = (x) - yyI1;\
sig = (*(F[(fno)]+yyI1)) + \
( (*(F[(fno)]+yyI2)) - (*(F[(fno)]+yyI1))) * yyA1;\
}
#define Sdelay(sig, delay_len, buflen, buf, bufptr)\
yyA2 = (*bufptr) - (delay_len);\
if ( yyA2 < 0.0 ) yyA2 += (buflen);\
yyI1 = (int)yyA2;\
yyI2 = yyI1 % (buflen);\
yyA1 = yyA2 - (int)yyA2;\
sig = *(buf+yyI1) + ( (*(buf+yyI2) - *(buf+yyI1)) * yyA1 )
#define Zdelay(sig, sigin, delay_len, buflen, buf, bufptr)\
yyI2 = (int)(*bufptr);\
if ( yyI2 > (buflen)) {\
(*bufptr) = 0.0;\
yyI2 = 0;\
}\
*(buf+yyI2) = sigin;\
yyA2 = (*bufptr) - (delay_len);\
yyI1 = (int)yyA2;\
yyI3 = yyI1 % (buflen);\
yyA1 = yyA2 - (int)yyA2;\
sig = *(buf+yyI1) + ( (*(buf+yyI3) - *(buf+yyI1)) * yyA1 )
#define Reverb(sig, xin, rvt, a )\
/* after Schroeder */\
/* dimension for "a" is (30 + 1538 * srate / 10000) - 1 */\
yyA1 = 0.0;\
yyA2 = 0.0;\
yyI2 = 0;\
for ( yyI1 = 0; yyI1 < 4; yyI1++ ) {\
Comb(yyA2, (xin), (rvt), a+yyI2 );\
yyA1 += yyA2;\
yyA2 = yyA1;\
yyI2 += (int)*(a+yyI2);\
}\
Alpass(yyA1, 0.096835, a+yyI2) * 0.25;\
yyI2 += (int)*(a+yyI2);\
Alpass(yyA1, 0.32924, a+yyI2);\
sig = yyA1\
/*-------------------------------------------------------------------------------*/